package logic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import bean.Arma;
import bean.Arma.Armas_Ids;
import bean.juego.Juego;
import bean.juego.JuegoCTF;
import bean.jugador.Jugador;
import java.util.*;
import util.Dummies;
import util.JugadoresComparator;
import logic.cache.CacheCaller;
import logic.cache.CacheService;
import util.JuegosComparator;

public class Buscador {

    private static final Map<String, Arma> mapaArmas = Collections.synchronizedMap(new HashMap<String, Arma>());
    private static final Map<String, Jugador> mapaJugadores = Collections.synchronizedMap(new HashMap<String, Jugador>());
    private static final Map<String, Jugador> mapaJugadoresPorApodo = Collections.synchronizedMap(new HashMap<String, Jugador>());
    private static final Map<String, Arma> mapaArmasPorApodo = Collections.synchronizedMap(new HashMap<String, Arma>());
    private static final Map<Date, Juego> mapaJuegos = Collections.synchronizedMap(new HashMap<Date, Juego>());

    public static Jugador jugadorPorApodo(String apodo) {
        if (apodo == null || apodo.equals("<world>")) {
            return Dummies.jugadorDummy;
        }

        Jugador jugador = mapaJugadoresPorApodo.get(apodo);

        if (jugador == null) {
            System.out.println("Jugador no conocido " + apodo);
            jugador = Dummies.jugadorDummy;
        }

        return jugador;
    }

    public static Arma armaPorId(String narma) {
        if (narma == null
                || narma.equals(Armas_Ids.MOD_FALLING.toString())
                || narma.equals(Armas_Ids.MOD_SUICIDE.toString())) {
            return Dummies.armaDummy;
        }

        Arma arma = mapaArmasPorApodo.get(narma);

        if (arma == null) {
            System.out.println("Arma no conocida " + narma);
            arma = Dummies.armaDummy;
        }

        return arma;
    }

    public static List<Arma> getArmas() {
        CacheCaller<List<Arma>> caller = new CacheCaller<List<Arma>>() {

            @Override
            public String getKey() {
                return Buscador.class.getName() + ".getArmas";
            }

            @Override
            public List<Arma> callMethod() {
                List<Arma> armas = new ArrayList<Arma>();
                armas.addAll(mapaArmas.values());
                Collections.sort(armas, new Comparator<Arma>() {

                    @Override
                    public int compare(Arma o1, Arma o2) {
                        return o1.getNombre().compareTo(o2.getNombre());
                    }
                });
                return Collections.unmodifiableList(armas);
            }
        };

        return CacheService.getFromCache(caller);
    }

    public static List<Jugador> getJugadores() {
        CacheCaller<List<Jugador>> caller = new CacheCaller<List<Jugador>>() {

            @Override
            public String getKey() {
                return Buscador.class.getName() + ".getJugadores";
            }

            @Override
            public List<Jugador> callMethod() {
                List<Jugador> jugadores = new ArrayList<Jugador>();
                jugadores.addAll(mapaJugadores.values());
                Collections.sort(jugadores, JugadoresComparator.getInstancia());

                return Collections.unmodifiableList(jugadores);
            }
        };

        return CacheService.getFromCache(caller);
    }

    public static List<Juego> getListaJuegos() {
        CacheCaller<List<Juego>> caller = new CacheCaller<List<Juego>>() {

            @Override
            public String getKey() {
                return Buscador.class.getName() + ".getListaJuegos";
            }

            @Override
            public List<Juego> callMethod() {
                List<Juego> juegos = new ArrayList<Juego>(mapaJuegos.size());
                juegos.addAll(mapaJuegos.values());
                Collections.sort(juegos, JuegosComparator.getInstancia());

                return Collections.unmodifiableList(juegos);
            }
        };

        return CacheService.getFromCache(caller);
    }

    public static Jugador getBot() {
        return jugadorPorApodo("Bot");
    }

    public static void addJuego(Juego juego) {
        if (!mapaJuegos.containsKey(juego.getFechaJuego())) {
            mapaJuegos.put(juego.getFechaJuego(), juego);
        }
    }

    public static Juego getJuego(Date fechaJuego) {
        return mapaJuegos.get(fechaJuego);
    }

    public static void addArma(Arma arma) {
        if (!mapaArmas.containsKey(arma.getNombre())) {
            mapaArmas.put(arma.getNombre(), arma);

            for (Arma.Armas_Ids apodo : arma.getApodos()) {
                mapaArmasPorApodo.put(apodo.toString(), arma);
            }
            mapaArmasPorApodo.put(arma.getNombre(), arma);
        }
    }

    public static void clearArmas() {
        CacheService.clear(Buscador.class.getName() + ".getArmas");
        mapaArmas.clear();
        mapaArmasPorApodo.clear();
    }

    public static void addJugador(Jugador jugador) {
        String nombre = jugador.getDatos().getNombre();
        if (!mapaJugadores.containsKey(nombre)) {
            mapaJugadores.put(nombre, jugador);

            for (String apodo : jugador.getDatos().getApodos()) {
                mapaJugadoresPorApodo.put(apodo, jugador);
            }
        }
    }

    public static void clearJugadores() {
        CacheService.clear(Buscador.class.getName() + ".getJugadores");
        mapaJugadores.clear();
        mapaJugadoresPorApodo.clear();
    }

    public static void clearJuegos() {
        CacheService.clear(Buscador.class.getName() + ".getListaJuegos");
        mapaJuegos.clear();
    }

    public static void clearAll() {
        clearJuegos();
        clearArmas();
        clearJugadores();
    }
}
